﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using _22_Bridge.Phone;
using _22_Bridge.Bride;
namespace _22_Bridge
{
    class Program
    {
        /*
         对象的继承关系是在编译时就定义好了，所以无法在运行时改变从父类继承的实现。子类的实现与它的父类有非常
         紧密的依赖关系，以至于父类的实现中的任何变化必然会导致子类发生变化。当你需要复用子类时，如果继承下来
         的实现不适合解决新的问题，则父类必须重写或被其他更合适的类替换。这种依赖关系限制了灵活性并最终限制了
         复用性。

         【合成/聚合复用原则】：合成(Composition) 和 聚合(Aggregation) 都是关联的特殊种类。聚合表示一种弱“拥
         有”关系，体现的是A对象可以包含B对象，但B对象不是A对象的一部分。 合成则是一种强的‘拥有’关系，体现了
         严格的部分和整体的关系，部分和整体的生命周期一样。

         合成/聚合复用原则的好处是，优先使用对象的和/聚合将有助于你保持没和类被封装，并集中在单个任务上。这样类
         类继承层次会保持较小规模，而且不太可能增长为不可控制的庞然大物。

         【桥接器模式(Bride)】：将抽象部分与它的实现部分分离，使它们都可以独立的变化。
            * 抽象与它的实现分离，并不是说，让抽象类与其派生类分离，因为这没有任何意义。实现指的是抽象类和他的派生
           类用来实现自己的对象。 
            * 有时候由于实现的方式有多种，桥接器模式的核心意图就是把这些实现独立出来，让他们各自的变化。这就使得每
            种实现的变化不会影响其他的实现，从而应对变化的目的。
           
            实现系统可能有多角度分类，每一类都有可能变化，那么就把这种多角度分离出来让他们独立变化，减少他们之间的
            耦合。 
            
            * 有时候在我们需要多角度去分类实现对象，而只用继承会造成大量的类增加，不能满足开放封闭原则时，就应该考
            率用桥接模式了。
        */
        static void Main(string[] args)
        {
            int type = 1;
            if (type == 2)
            {
                PhoneCode();
            }
            else
            {
                Bride();
            }

            Console.Read();
        }
        private static void Bride()
        {
            Abstraction ab = new RefinedAbstraction();

            ab.SetImplementor(new ConcreteImplementorA());
            ab.Operation();

            ab.SetImplementor(new ConcreteImplementorB());
            ab.Operation();

            Console.Read();
        }
        private static void PhoneCode()
        {
            HandsetBrand ab;
            ab = new HandsetBrandN();
            Console.WriteLine("手机品牌N");
            ab.SetHandSetSoft(new HandsetGame());
            ab.Run();

            ab.SetHandSetSoft(new HandsetAddressList());
            ab.Run();

            //手机品牌M
            ab = new HandsetBrandM();
            Console.WriteLine("手机品牌M");
            ab.SetHandSetSoft(new HandsetGame());
            ab.Run();

            ab.SetHandSetSoft(new HandsetAddressList());
            ab.Run();
        }
    }
}
